import logging
import allure
from utils.get_keywords import GetKeywords
from utils.base_asserts import MainAsserts
from abc import ABC, abstractmethod


class DataAssert(ABC):
    @abstractmethod
    def http_assert(self):
        pass


class SingleAssert(DataAssert):
    @allure.step("3.HTTP响应断言")
    def http_assert(self, case, res):
        if case["check"]:
            result = GetKeywords.get_keyword(res, case["check"])
            logging.info(f"3.HTTP响应断言内容: 实际结果({result}) == 预期结果({case['expected']})")
            assert result == case["expected"]
        else:
            logging.info(f"3.HTTP响应断言内容: 预期结果({case['expected']}) in 实际结果({str(res)})")
            assert case["expected"] in str(res)

class MultipleAssert(DataAssert):
    @allure.step("3.HTTP多重响应断言")
    def http_assert(self, case, res):
        if case["check"]:
            MainAsserts(case, res).main_assert()

def obj_processor(case):
    """
    对象处理，根据传入的case的不同，来返回不同的对象
    :return:
    """
    try:
        # 可能出现异常的代码
        eval(case["check"])
    except:
        # 出现异常之后，表示断言不是字典，因此走老逻辑
        # 返回单个断言的对象
        return SingleAssert()
    else:
        # 没有出现异常，表示可以转成字典，走多重断言的逻辑
        return MultipleAssert()


def http_assert(case, res):
    """
    真正的调用逻辑，后续无论怎么新增http返回值的断言，都是调用这个函数
    :param case: 测试用例
    :param res: 返回结果
    :return:
    """
    obj_processor(case).http_assert(case, res)



